package com.lnsf.bookstore.common.aop;

import com.lnsf.bookstore.common.annotation.SysLog;
import com.lnsf.bookstore.common.session.SessionProvider;
import com.lnsf.bookstore.system.log.service.LogService;
import com.lnsf.bookstore.system.log.vo.Log;
import com.lnsf.bookstore.system.user.vo.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;


/**
 * 系统日志，切面处理类
 *
 * @author lipengjun
 * @email 939961241@qq.com
 * @date 2017年3月8日 上午11:07:35
 */
@Aspect
@Component
public class LogAspect {
    @Autowired
    private LogService logService;

    @Autowired
    private SessionProvider sessionProvider;

    /**
     * 开始时间
     */
    private long startTime = 0L;
    /**
     * 结束时间
     */
    private long endTime = 0L;

    /**
     * 切点
     */
    @Pointcut("@annotation(com.lnsf.bookstore.common.annotation.SysLog)")
    public void logPointCut() {

    }

    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("logPointCut()")
    public void doBeforeInServiceLayer(JoinPoint joinPoint) {
        startTime = System.currentTimeMillis();
    }
    /**
     * 环绕通知
     * @param joinPoint
     */
    @Around("logPointCut()")
    public Object saveSysLog(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log log = new Log();
        SysLog syslog = method.getAnnotation(SysLog.class);
        if (syslog != null) {
            //注解上的描述
            log.setContent(syslog.value());
        }
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.setMethod(className + "." + methodName + "()");

        //请求的参数
       /* Object[] args = joinPoint.getArgs();
        String params = JSON.toJSONString(args[0]);
        log.setParams(params);*/

        //获取request
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //设置IP地址
        /*log.setUserIp(IPUtils.getIpAddr(request));*/
        log.setUserIp(request.getRemoteAddr());
        //设置url
        log.setUrl(request.getRequestURI());
        // 环绕通知 ProceedingJoinPoint执行proceed方法的作用是让目标方法执行，这也是环绕通知和前置、后置通知方法的一个最大区别。
        Object result = joinPoint.proceed();
        endTime = System.currentTimeMillis();
        //耗时
        log.setSpendTime((int) (endTime-startTime));
        //用户名
        User user = sessionProvider.getUser();
        Integer userId = 0;
        /*if ("login".equals(methodName)) {
            username = params;
        }*/
        if (null != user) {
            userId = sessionProvider.getUser().getId();
        }
        log.setUserId(userId);

        log.setCreateTime(new Date());
        //保存系统日志
        logService.save(log);

        return result;
    }

}
